#include "Menu.hh"
#include <iostream>

Menu::Menu(Room* room, Character* character) : currentRoom(room), player(character) {
    // Constructor logic if needed
}
#include <cstdlib> 
#include <cstdio> 
Menu::~Menu() {
delete currentRoom;
delete player; // Release the dynamically allocated memory
}// Destructor logic if needed

Menu::Menu(const Menu& other) {
    currentRoom = other.currentRoom; // Shallow copy, assuming Room has proper copy constructor
    player = other.player; // Shallow copy, assuming Character has proper copy constructor
}
Menu& Menu::operator=(const Menu& other) {
    if (this != &other) {
        currentRoom = other.currentRoom; // Shallow copy, assuming Room has proper copy constructor
        player = other.player; // Shallow copy, assuming Character has proper copy constructor
    }
    return *this;
}
void Menu::clearScreen() {
        #ifdef _WIN32 // 
            system("cls");
        #else // 
            system("clear");
        #endif
        // Clear the input buffer
        std::cin.clear();
        std::cin.ignore(100, '\n');
    }
void Menu::setCurrentRoom(Room* room) {
        currentRoom = room;
    }
void Menu::displayRoomMenu() {
    clearScreen();

    std::cout << "=== " << currentRoom->getDescription() << " ===" << std::endl;
    std::cout << "Items here: ";
    if (currentRoom->getItems().empty()) {
        std::cout << "None" << std::endl;
    } else {
        for (const auto& item : currentRoom->getItems()) {
            std::cout << item->getName() << ", ";
        }
        std::cout << std::endl;
    }

    std::cout << "Enemies here: ";
    if (currentRoom->getEnemies().empty()) {
        std::cout << "None" << std::endl;
    } else {
        for (const auto& enemy : currentRoom->getEnemies()) {
            std::cout << enemy->toString() << ", ";
        }
        std::cout << std::endl;
    }

    std::cout << "Your HP: " << player->getHealth() << "/" << player->getMaxHealth() << std::endl;

    std::cout << "What would you like to do?" << std::endl;
    std::cout << "1. Move north" << std::endl;
    std::cout << "2. Move south" << std::endl;
    std::cout << "3. Move east" << std::endl;
    std::cout << "4. Move west" << std::endl;
    std::cout << "5. Take item" << std::endl;
    std::cout << "6. Attack enemy" << std::endl;
    std::cout << "7. Heal self" << std::endl;
    std::cout << "8. View inventory" << std::endl;
    std::cout << "9. View stats" << std::endl;
    std::cout << "10. Exit game" << std::endl;

    std::cout << "Enter your choice (1-10): ";
}

void Menu::displayInventoryMenu() {
    clearScreen();
    std::cout << "=== Inventory ===" << std::endl;
    player->displayInventory();
    std::cout << "Press any key to return to the main menu: ";
    std::cin.get();
}

void Menu::displayStatsMenu() {
    clearScreen();
    std::cout << "=== Player Stats ===" << std::endl;
    player->display();
    std::cout << "Press any key to return to the main menu: ";
    std::cin.get();
}

void Menu::displayTakeItemMenu() {
    clearScreen();
    std::cout << "=== Take Item ===" << std::endl;
    
    // Obtain the list of items in the current room once
    const auto& items = currentRoom->getItems();

    if (items.empty()) {
        std::cout << "There are no items to take." << std::endl;
    } else {
        std::cout << "Available items:" << std::endl;
        for (size_t i = 0; i < items.size(); ++i) {
            std::cout << i + 1 << ". " << items[i]->getName() << " - " << items[i]->getDescription() << std::endl;
        }
        
        int choice;
        std::cout << "Enter the number of the item you want to take (or 0 to cancel): ";
        std::cin >> choice;

        if (choice > 0 && choice <= static_cast<int>(items.size())) {
            // Obtain the item pointer corresponding to the index
            Item* selectedItem = items[choice - 1];
            player->addToInventory(selectedItem);
            
            // Call removeItem and pass the item pointe
            currentRoom->removeItem(selectedItem);
            std::cout << "You picked up the item!" << std::endl;
        } else if (choice != 0) {
            std::cout << "Invalid choice. Please try again." << std::endl;
        }
    }

    // Print the remaining items for debugging
    std::cout << "Remaining items in room: " << std::endl;
    for (const auto& item : currentRoom->getItems()) {
        std::cout << item->getName() << std::endl;
    }

    std::cout << "Press any key to return to the main menu: ";
    std::cin.ignore();  // Ignore the previous line break character
    std::cin.get();
}

void Menu::displayAttackEnemyMenu() {
    clearScreen();
    std::cout << "=== Attack Enemy ===" << std::endl;
    if (currentRoom->getEnemies().empty()) {
        std::cout << "There are no enemies to attack." << std::endl;
    } else {
        std::cout << "Available enemies:" << std::endl;
        for (size_t i = 0; i < currentRoom->getEnemies().size(); ++i) {
            std::cout << i + 1 << ". " << currentRoom->getEnemies()[i]->toString() << std::endl;
        }
        std::cout << "Enter the number of the enemy you want to attack (or 0 to cancel): ";
        int choice;
        std::cin >> choice;
        if (choice > 0 && choice <= static_cast<int>(currentRoom->getEnemies().size())) {
            ICharacter& enemy = *currentRoom->getEnemies()[choice - 1];
            displayBattleMenu(enemy);
            if (!enemy.isAlive()) {
                currentRoom->removeEnemy(&enemy);
            }
        } else if (choice != 0) {
            std::cout << "Invalid choice. Please try again." << std::endl;
        }
    }
    std::cout << "Press any key to return to the main menu: ";
    std::cin.ignore(); 
    std::cin.get();
}

void Menu::displayBattleMenu(ICharacter& enemy) {
    bool battleOver = false;

    clearScreen();
    std::cout << "=== Enemy Background ===" << std::endl;
    std::cout << enemy.getDescription() << std::endl;
    std::cout << "\nPress any key to continue to battle...";
    std::cin.clear();
    std::cin.ignore();
    std::cin.get();

    while (player->isAlive() && enemy.isAlive() && !battleOver) {
        std::cout << "=== Battle ===" << std::endl;
        std::cout << "Your HP: " << player->getHealth() << "/" << player->getMaxHealth() << std::endl;
        std::cout << "Enemy: " << enemy.toString() << std::endl;

        std::cout << "What would you like to do?" << std::endl;
        std::cout << "1. Attack" << std::endl;
        std::cout << "2. Heal" << std::endl;
        std::cout << "Enter your choice (1-2): ";

        int choice;
        std::cin >> choice;

        switch (choice) {
            case 1:
                if (player->attack(enemy)) {
                    std::cout << "You attacked the enemy!!!!!" << std::endl;
                } else {
                    std::cout << "The enemy is dead!" << std::endl;

                    std::cout << "You defeated the enemy!" << std::endl;
                    battleOver = true; // Set the flag to end the battle
                }
                break;
            case 2:
                player->heal(50); // Heal 50 HP
                std::cout << "You healed 50 HP." << std::endl;
                break;
            default:
                std::cout << "Invalid choice. Please try again." << std::endl;
                break;
        }

        if (enemy.isAlive()) {
            if (enemy.attack(*player)) {
                std::cout << "The enemy attacked you!" << std::endl;
            } else {
                std::cout << "You are dead!" << std::endl;
                battleOver = true; // Set the flag to end the battle
            }
        }
    }
}

void Menu::displayMenu() {
    displayRoomMenu();
}

int Menu::getPlayerChoice() {
    int choice;
    while (true) {
        displayMenu();
        std::cin >> choice;
        if (choice >= 1 && choice <= 10) {
            return choice;
        } else {
            std::cout << "Invalid choice. Please try again." << std::endl;
        }
    }
}
